package ngat.oss;

import ngat.message.OSS.*;
import ngat.util.logging.*;
import ngat.phase2.*; 
import ngat.instrument.*;
import ngat.phase2.nonpersist.*;

import java.util.*;
import java.io.*;

import jyd.dbms.*;
import jyd.storable.*;
import jyd.collection.*;

/**
 * Action: Sent by USR to retreive data about all available Proposals. 
 * @author S.N.Fraser
 */
public class LIST_PROPOSALSImpl extends TransactionImpl implements Serializable {
    
    // ### We may want to specifiy whether we want PI, COI or BOTH
    // ### in the returned data.


    /** The path used to locate the User in the OSS database. */
    protected Path userPath;
 
    /** Create a LIST_PROPOSALSImpl for the supplied request.*/
    public LIST_PROPOSALSImpl(LIST_PROPOSALS request) {
	super(request);
	this.userPath = request.getUserPath();
    }

    /**
     * Retrieves the List of Proposals for User specified
     * @return list or an OSS_Error.
     */
    public TRANSACTION_DONE exec() { 
	
	myLog = LogManager.getLogger("TRACE");

	User user = null;
	Proposal proposal = null;

	Vector plist = new Vector(); // Holds the list of Proposal paths.
	
	Transaction t = null;
	try {
	    t = Transaction.current();
	    myLog.log(1, CLASS, id, "exec", "List proposals for user: "+userPath.toString());

	    user = OSS_Utilities.fetchUser(userPath);
	    myLog.log(1, CLASS, id, "exec", "Retrieved user details");

	    // Check it exists.
	    if (user == null) {
		logger.log(1, CLASS, id, "exec", 
			   "User: "+userPath.toString()+" Not in database.");
		return error(TRANSACTION.PATH_RESOLUTION_ERROR, 
				     "Could not find User: "+userPath.toString());
	    }
	    
	    // Iterate round the User's PI Proposals.
	    Iterator it = user.listAllProposals();	
	    myLog.log(1, CLASS, id, "exec", "Listing proposals with PI status...");
	    while (it.hasNext()) {
		KVPair pair = (KVPair)it.next();
		String name = (String)pair.getKey();
		myLog.log(1, CLASS, id, "exec", "Extracting proposal: "+name);
		try {
		    proposal = OSS_Utilities.fetchProposal(new Path(userPath.toString(),name));
		    if (proposal != null) { 	 	    
			plist.addElement(proposal.getDescriptor());
			myLog.log(1, "Added PI Proposal: "+proposal.getFullPath());
		    }
		} catch (Exception iox) {
		    logger.log(1, CLASS, id, "exec",
			       "Proposal: "+name+
			       " Error fetching from Database: "+iox);
		}
	    }
	    
	    // Iterate round the User's CoI Proposals.
	    it = user.listAllCoIProposals();
	    myLog.log(1, CLASS, id, "exec", "Listing proposals with CoI status...");
	    while (it.hasNext()) {
		KVPair pair = (KVPair)it.next();
		String name = (String)pair.getKey();
		myLog.log(1, CLASS, id, "exec", "Extracting proposal: "+name);
		try {
		    Path path = new Path(name);
		    proposal = OSS_Utilities.fetchProposal(path);
		    if (proposal != null) {	
			plist.addElement(proposal.getDescriptor());
			myLog.log(1, "Added CoI Proposal: "+proposal.getFullPath());

			// ### Get the UserDescriptor for the PI user, and check we
			// ### dont already have it.
			
			//User pi = OSS_Utilities.fetchUser(path);
			//if (pi != null) {
			//  // have we got him ?
			//  if not then
			//  ulist.add(pi.getDescriptor());
			//}


		    }
		} catch (IOException iox) {
		    logger.log(1, CLASS, id, "exec",
			       "Proposal: "+name+
			       " Error fetching from Database: "+iox);
		}
	    }
	    
	} finally {
	    t.commit();
	}
	
	LIST_PROPOSALS_DONE done  = new LIST_PROPOSALS_DONE(id);
	done.setProposalList(plist);
	done.setSuccessful(true);
	return done;

    }
    
    
}

